/**
 * 性能监控工具
 * @description 用于跟踪页面加载性能、绘制指标、代码分割效果等性能数据
 * @author 系统开发团队
 * @version 1.0.0
 */

// ==================== 接口定义 ====================

/**
 * 性能指标接口
 * @description 定义各种性能监控指标的数据结构
 */
interface PerformanceMetrics {
    /** 页面加载时间（毫秒） */
    pageLoadTime: number
    /** DOM内容加载时间（毫秒） */
    domContentLoaded: number
    /** 首次内容绘制时间（毫秒） */
    firstContentfulPaint: number
    /** 最大内容绘制时间（毫秒） */
    largestContentfulPaint: number
    /** 代码块加载时间记录，key为代码块名称，value为加载时间 */
    chunkLoadTimes: Record<string, number>
}

// ==================== 性能监控器类 ====================

/**
 * 性能监控器类
 * @description 提供页面性能监控、绘制指标测量、代码分割分析等功能
 */
class PerformanceMonitor {
    /** 性能指标数据存储 */
    private metrics: PerformanceMetrics = {
        pageLoadTime: 0,
        domContentLoaded: 0,
        firstContentfulPaint: 0,
        largestContentfulPaint: 0,
        chunkLoadTimes: {}
    }

    /**
     * 初始化性能监控
     * @description 启动所有性能监控功能，包括页面加载、绘制指标和代码块加载时间监控
     * @example
     * performanceMonitor.init()
     */
    init() {
        this.measurePageLoad()
        this.measurePaintMetrics()
        this.measureChunkLoadTimes()
    }

    /**
     * 测量页面加载时间
     * @description 监听页面load事件，测量页面加载时间和DOM内容加载时间
     * @private
     */
    private measurePageLoad() {
        window.addEventListener('load', () => {
            // 获取导航性能数据
            const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming
            
            // 计算页面加载时间
            this.metrics.pageLoadTime = navigation.loadEventEnd - navigation.loadEventStart
            // 计算DOM内容加载时间
            this.metrics.domContentLoaded = navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart

            console.log('页面加载性能:', {
                '页面加载时间': `${this.metrics.pageLoadTime}ms`,
                'DOM内容加载时间': `${this.metrics.domContentLoaded}ms`
            })
        })
    }

    /**
     * 测量绘制指标
     * @description 使用PerformanceObserver监听绘制相关指标，包括FCP和LCP
     * @private
     */
    private measurePaintMetrics() {
        // 首次内容绘制 (FCP) - 测量页面首次绘制内容的时间
        new PerformanceObserver((list) => {
            const entries = list.getEntries()
            entries.forEach((entry) => {
                if (entry.name === 'first-contentful-paint') {
                    this.metrics.firstContentfulPaint = entry.startTime
                    console.log('首次内容绘制 (FCP):', `${entry.startTime}ms`)
                }
            })
        }).observe({ entryTypes: ['paint'] })

        // 最大内容绘制 (LCP) - 测量页面最大内容元素绘制的时间
        new PerformanceObserver((list) => {
            const entries = list.getEntries()
            entries.forEach((entry) => {
                this.metrics.largestContentfulPaint = entry.startTime
                console.log('最大内容绘制 (LCP):', `${entry.startTime}ms`)
            })
        }).observe({ entryTypes: ['largest-contentful-paint'] })
    }

    /**
     * 测量代码块加载时间
     * @description 监听资源加载事件，特别关注代码块（chunk）的加载时间
     * @private
     */
    private measureChunkLoadTimes() {
        // 监听资源加载事件
        new PerformanceObserver((list) => {
            const entries = list.getEntries()
            entries.forEach((entry) => {
                const resourceEntry = entry as PerformanceResourceTiming
                // 检查是否为代码块文件（.js文件且包含chunk标识）
                if (resourceEntry.name.includes('.js') && resourceEntry.name.includes('chunk')) {
                    const chunkName = this.extractChunkName(resourceEntry.name)
                    this.metrics.chunkLoadTimes[chunkName] = resourceEntry.duration
                    console.log(`代码块加载时间 (${chunkName}):`, `${resourceEntry.duration}ms`)
                }
            })
        }).observe({ entryTypes: ['resource'] })
    }

    /**
     * 提取代码块名称
     * @description 从URL中提取代码块的名称，去除哈希值
     * @param {string} url 代码块文件的URL
     * @returns {string} 提取的代码块名称
     * @private
     * @example
     * const name = extractChunkName('/assets/chunk-vendor-a1b2c3d4.js')
     * // 返回: 'chunk-vendor'
     */
    private extractChunkName(url: string): string {
        const match = url.match(/([^/]+)-[a-f0-9]+\.js$/)
        return match ? match[1] : 'unknown'
    }

    /**
     * 获取性能指标
     * @description 返回当前收集的所有性能指标数据
     * @returns {PerformanceMetrics} 性能指标对象
     * @example
     * const metrics = performanceMonitor.getMetrics()
     * console.log('页面加载时间:', metrics.pageLoadTime)
     */
    getMetrics(): PerformanceMetrics {
        return { ...this.metrics }
    }

    /**
     * 分析代码分割效果
     * @description 分析代码分割的性能效果，包括代码块数量、总加载时间等统计信息
     * @example
     * performanceMonitor.analyzeCodeSplitting()
     * // 输出: 代码分割分析: { 代码块数量: 5, 总加载时间: "1200ms", ... }
     */
    analyzeCodeSplitting() {
        const chunks = Object.keys(this.metrics.chunkLoadTimes)
        const totalChunkTime = Object.values(this.metrics.chunkLoadTimes).reduce((sum, time) => sum + time, 0)

        console.log('代码分割分析:', {
            '代码块数量': chunks.length,
            '总加载时间': `${totalChunkTime}ms`,
            '平均加载时间': `${totalChunkTime / chunks.length}ms`,
            '代码块列表': chunks
        })
    }

    /**
     * 检查性能是否达标
     * @description 根据性能标准检查当前页面性能是否达到预期目标
     * @returns {boolean} 性能是否达标
     * @example
     * const isGood = performanceMonitor.checkPerformance()
     * if (isGood) {
     *   console.log('性能表现优秀')
     * } else {
     *   console.log('需要性能优化')
     * }
     */
    checkPerformance(): boolean {
        // 性能标准：
        // - 页面加载时间 < 3秒
        // - 首次内容绘制 < 2秒
        // - 最大内容绘制 < 2.5秒
        const isGood =
            this.metrics.pageLoadTime < 3000 &&
            this.metrics.firstContentfulPaint < 2000 &&
            this.metrics.largestContentfulPaint < 2500

        console.log('性能检查结果:', isGood ? '✅ 优秀' : '❌ 需要优化')
        return isGood
    }
}

// ==================== 实例和自动初始化 ====================

/** 全局性能监控实例 */
export const performanceMonitor = new PerformanceMonitor()

/**
 * 自动初始化性能监控
 * @description 在浏览器环境中自动启动性能监控
 */
if (typeof window !== 'undefined') {
    performanceMonitor.init()
} 